﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using viBlog.Classes;
using viBlog.Providers;
using visinia.SmartEngine.Cache;

namespace viBlog.Controllers
{
    /// <summary>
    /// The blog posts tags controller
    /// </summary>
    public class TagController
    {
        /// <summary>
        /// Gets all the tags
        /// </summary>
        /// <returns>List of all tags</returns>
        public static List<Tag> GetTags()
        {
            List<Tag> list = (List<Tag>)DataCache.GetCache("viBlogtags");
            if (list == null)
            {
                list = FillTags(viBlogDataProvider.Provider.GetTags());
                DataCache.SetCache("viBlogtags", list);
            }
            return list;
        }

        /// <summary>
        /// Gets the tag by its name
        /// </summary>
        /// <param name="TagName"></param>
        /// <returns></returns>
        public static Tag GetTag(string TagName)
        {  
            return GetTags().Find(p => (string.Compare(p.Name, TagName, true) == 0));
        }

        /// <summary>
        /// Gets the tag by its unique tag id
        /// </summary>
        /// <param name="tagid"></param>
        /// <returns></returns>
        public static Tag GetTag(int tagid)
        {
            return GetTags().Find(p => p.TagId == tagid);
        }

        /// <summary>
        /// Gets tags for a specified Post
        /// </summary>
        /// <param name="PostId">Post id</param>
        /// <returns>List of tags</returns>
        public static List<Tag> GetTags(int PostId)
        {
            string key = string.Format("viBlogtags_{0}", PostId);
            List<Tag> list = (List<Tag>)DataCache.GetCache(key);
            if (list == null)
            {
                list = FillTags(viBlogDataProvider.Provider.GetTags(PostId));
                DataCache.SetCache(key, list);
            }
            return list;
        }

        /// <summary>
        /// Gets the data for the tags clouds (this will not return empty tags)
        /// </summary>
        /// <returns></returns>
        public static List<DataCount> GetTagCount()
        {
            List<DataCount> list = (List<DataCount>)DataCache.GetCache("viBlogtagsCount");
            if (list == null)
            {
                list = FillTagCount(viBlogDataProvider.Provider.GetTagCount());
                DataCache.SetCache("viBlogtagsCount", list);
            }
            return list;
        }

        #region DATA
        public static void ResetTags(int PostId)
        {
            GetTags(PostId).ForEach(delegate(Tag tag)
            {
                RemoveTag(tag.TagId, PostId);
            });
            DataCache.DeleteCacheMultiple("viBlogtags");
        }
        /// <summary>
        /// Associates a tag to a post
        /// </summary>
        /// <param name="TagId"></param>
        /// <param name="PostId"></param>
        public static void InsertTag(int TagId, int PostId)
        {
            viBlogDataProvider.Provider.InsertTag(TagId, PostId);
            DataCache.DeleteCacheMultiple("viBlogtags");
        }

        /// <summary>
        /// Removes the specified tag and specified post association
        /// </summary>
        /// <param name="TagId"></param>
        /// <param name="PostId"></param>
        public static void RemoveTag(int TagId, int PostId)
        {
            viBlogDataProvider.Provider.RemoveTag(TagId, PostId);
            DataCache.DeleteCacheMultiple("viBlogtags");
        }

        /// <summary>
        /// Adds a new tag
        /// </summary>
        /// <param name="tag"></param>
        public static int AddTag(Tag tag)
        {
            IDataReader dr = viBlogDataProvider.Provider.AddTag(tag.Name.Trim());
            int index = 0;
            while (dr.Read())
            {
                if (dr[0] != Convert.DBNull)
                    index = (int)dr[0];
            }
            dr.Close();
            DataCache.DeleteCacheMultiple("viBlogtags");
            return index; 
        }

        /// <summary>
        /// Deletes a tag
        /// </summary>
        /// <param name="TagId"></param>
        public static void DeleteTag(int TagId)
        {
            viBlogDataProvider.Provider.DeleteTag(TagId);
            DataCache.DeleteCacheMultiple("viBlogtags");
        }
        #endregion

        #region HELPERS
        private static List<DataCount> FillTagCount(IDataReader dr)
        {
            List<DataCount> list = new List<DataCount>();
            while (dr.Read())
            {
                list.Add(ActualReadTagsCount(dr));
            }
            dr.Close();
            return list;
        }
        private static DataCount ActualReadTagsCount(IDataReader dr)
        {
            DataCount data = new DataCount();
            if (dr["DataId"] != Convert.DBNull)
                data.DataId = (int)dr["DataId"];
            if (dr["Count"] != Convert.DBNull)
                data.Count = (int)dr["Count"];
            return data;
        }        
        private static List<Tag> FillTags(IDataReader dr)
        {
            List<Tag> list = new List<Tag>();
            while (dr.Read())
            {
                list.Add(ActualRead(dr));
            }
            dr.Close();
            return list;
        }
        private static Tag ActualRead(IDataReader dr)
        {
            Tag tag = new Tag();
            if (dr["TagId"] != Convert.DBNull)
                tag.TagId = (int)dr["TagId"];
            if (dr["Name"] != Convert.DBNull)
                tag.Name = HttpUtility.HtmlEncode((string)dr["Name"]);
            return tag;
        }
        #endregion
    }
}
